package com.jshan.utils;

import cn.dev33.satoken.stp.StpUtil;
import com.jshan.base.dto.DashboardDto;
import com.jshan.base.entity.SysContent;
import com.jshan.base.entity.SysOperationLog;
import com.jshan.base.vo.Result;
import com.jshan.service.SysContentService;
import com.jshan.service.SysOperationLogService;
import com.jshan.service.SysUserService;
import com.sun.management.OperatingSystemMXBean;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.io.File;
import java.lang.management.ManagementFactory;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
@RequiredArgsConstructor
public class DashboardUtils {

    private final SysUserService userService;
    private final SysOperationLogService operationLogService;
    private final SysContentService contentService;

    /**
     * 获取机器相关信息
     *
     * @return Result
     */
    public Result phyInfo() {
        Map<String, Object> data = new HashMap<>();
        // 内存信息
        OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory
                .getOperatingSystemMXBean();
        long totalMemory = osmxb.getTotalMemorySize();
        long freeMemory = osmxb.getFreeMemorySize();
        long usedMemory = totalMemory - freeMemory;
        Map<String, Object> memory = new HashMap<>();
        memory.put("total", totalMemory);
        memory.put("used", usedMemory);
        memory.put("free", freeMemory);
        data.put("memory", memory);
        // 硬盘信息
        List<Map<String, Object>> disks = new ArrayList<>();
        File[] roots = File.listRoots();
        for (File root : roots) {
            Map<String, Object> disk = new HashMap<>();
            disk.put("name", root.getPath());
            disk.put("total", root.getTotalSpace());
            disk.put("free", root.getFreeSpace());
            disk.put("used", root.getTotalSpace() - root.getFreeSpace());
            disks.add(disk);
        }
        data.put("disks", disks);
        return Result.ok(data);
    }

    /**
     * 获取统计图数据（日志数据）
     *
     * @return result
     */
    public Result findWeekChars() {
        List<String> days = new ArrayList<>();
        List<Long> counts = new ArrayList<>();
        LocalDateTime now = LocalDateTime.now();
        for (int i = 6; i >= 0; i--) {
            LocalDateTime dayStart = now.minusDays(i).withHour(0).withMinute(0).withSecond(0).withNano(0);
            LocalDateTime dayEnd = dayStart.plusDays(1).minusNanos(1);
            long count = operationLogService.lambdaQuery()
                    .ge(SysOperationLog::getCreateTime, dayStart)
                    .le(SysOperationLog::getCreateTime, dayEnd)
                    .count();
            days.add(dayStart.toLocalDate().toString());
            counts.add(count);
        }
        // 返回格式：{"days": [...], "counts": [...]}
        Map<String, Object> data = new HashMap<>();
        data.put("days", days);
        data.put("counts", counts);
        return Result.ok(data);
    }

    /**
     * 获取首页top行内容
     *
     * @return result
     */
    public Result findTopList() {

        List<DashboardDto> list = new ArrayList<>();
        list.add(createDashboard("#409EFF", "用户数量", "User", userService.count()));
        list.add(createDashboard("#13ce66", "在线用户数", "View", onLineCount()));
        list.add(createDashboard("#ffba00", "近一周访问数量", "QuestionFilled", countWeekLog()));
        list.add(createDashboard("#a084e8", "文章数量", "Document", countContent()));
        list.add(createDashboard("#ff4d4f", "新增文章", "Share", countAddContent()));
        list.add(createDashboard("#e15b99", "新增互动", "ChatDotRound", 12L));

        return Result.ok(list);
    }

    /**
     * 今日新增文章数量
     *
     * @return long
     */
    private Long countAddContent() {
        LocalDate now = LocalDate.now();
        return contentService.lambdaQuery()
                .ge(SysContent::getCreateTime, now)
                .or(r -> r.ge(SysContent::getUpdateTime, now))
                .count();
    }

    /**
     * 统计发布文章数量
     *
     * @return long
     */
    private Long countContent() {
        return contentService.count();
    }

    /**
     * 获取近一周的访问日志数量
     *
     * @return long
     */
    private Long countWeekLog() {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime weekTime = now.minusWeeks(1);
        return operationLogService.lambdaQuery()
                .ge(SysOperationLog::getCreateTime, weekTime)
                .le(SysOperationLog::getCreateTime, now)
                .count();
    }

    /**
     * 统计在线用户数量
     *
     * @return Long
     */
    private Long onLineCount() {
        List<String> strings = StpUtil.searchTokenValue("", 0, -1, false);
        return (long) strings.size();
    }

    /**
     * 生成实体方法
     *
     * @param color 颜色
     * @param label 名称
     * @param icon  图标
     * @param value 数量
     * @return 对象
     */
    private DashboardDto createDashboard(String color, String label, String icon, Long value) {
        DashboardDto dashboardDto = new DashboardDto();
        dashboardDto.setColor(color);
        dashboardDto.setLabel(label);
        dashboardDto.setIcon(icon);
        dashboardDto.setValue(value);
        return dashboardDto;
    }

}
